/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package de.blitzcoder.collide.gui;

import de.blitzcoder.collide.Interface;
import de.blitzcoder.collide.engine.parser.CodeParser;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.LinkedList;
import java.util.ListIterator;
import java.util.Timer;
import java.util.TimerTask;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import org.gjt.sp.jedit.buffer.BufferListener;
import org.gjt.sp.jedit.buffer.JEditBuffer;

/**
 *
 * @author blitzcoder
 */
public class BlitzMaxCodeDocument extends CodeDocument implements BufferListener {

    // Der Parser, der Timer und sein Task
    private CodeParser parser;
    private Timer parserTimer;
    private ParserTimerTask parserTimerTask;

    // Zeitpunkt der letzten Änderung am Code
    private long lastAction = System.currentTimeMillis();

    // Liste mit ParserListenern
    private LinkedList<ParserListener> parserListenerList;

    public BlitzMaxCodeDocument(File file) throws Exception {
        super(file, "blitzmax.xml");

        parser = new CodeParser();
        parserTimer = new Timer();
        parserTimerTask = new ParserTimerTask();

        parserTimer.schedule(parserTimerTask, 0, 600);

        parserListenerList = new LinkedList<ParserListener>();

        System.out.println("Creating BMax Docuemnt");

    }

    private String checkEndRem(String code) {

        // ^\W*EndRem\W*$
        Matcher matcher = Pattern.compile("^\\W*End\\s+Rem\\W*$", Pattern.MULTILINE).matcher(code);
        if (matcher.find()) {

            int retVal = JOptionPane.showConfirmDialog(Interface.getDialogParent(), "Die Datei " + file.getName() + " enthällt End Rem (Mit Leerzeichen).\n\nDurch einen Bug in der Textarea von jEdit, welche hier verwendet wird,\nist es nicht möglich diese Kommentare ordentlich zu highlighten.\nSollen alle End Rem's automatisch nach EndRem (Ohne Leerzeichen) konvertiert werden?", "Kommentarhighlighting", JOptionPane.OK_CANCEL_OPTION);

            if (retVal == JOptionPane.OK_OPTION) {
                saved = false;

                return Pattern.compile("End\\s*Rem\\W*$", Pattern.MULTILINE).matcher(code).replaceAll("EndRem\n");
            }

            return null;

        } else {
            return null;
        }

    }

    public void addParserListener(ParserListener lis) {
        parserListenerList.addLast(lis);
    }

    public void removeParserListener(ParserListener lis) {
        parserListenerList.remove(lis);
    }

    private void fireParserUpdate() {
        ListIterator<ParserListener> it = parserListenerList.listIterator();
        while (it.hasNext()) {
            it.next().parserUpdate(this);
        }
    }

    public CodeParser getParser() {
        return parser;
    }

    public void load() throws Exception {
        super.load();

        String corrected = checkEndRem(textArea.getText());
        if (corrected != null)
            textArea.setText(corrected);

        textArea.getBuffer().addBufferListener(new BlitzMaxCorrectionBufferListener(textArea));
        getTextArea().getBuffer().addBufferListener(this);
    }

    @Override
    public void contentInserted(JEditBuffer arg0, int arg1, int arg2, int arg3, int arg4) {
        lastAction = System.currentTimeMillis();
    }

    @Override
    public void contentRemoved(JEditBuffer arg0, int arg1, int arg2, int arg3, int arg4) {
        lastAction = System.currentTimeMillis();
    }

    public void foldLevelChanged(JEditBuffer arg0, int arg1, int arg2) {
    }

    public void preContentInserted(JEditBuffer arg0, int arg1, int arg2, int arg3, int arg4) {
    }

    public void preContentRemoved(JEditBuffer arg0, int arg1, int arg2, int arg3, int arg4) {
    }

    public void transactionComplete(JEditBuffer arg0) {
    }

    public void foldHandlerChanged(JEditBuffer arg0) {
    }

    public void bufferLoaded(JEditBuffer arg0) {
    }

    private class ParserTimerTask extends TimerTask {

        public void run() {
            if (finishedLoading && lastAction != -1 && System.currentTimeMillis() - lastAction > 600) {
                parser.parse(getTextArea().getText(), getFile());
                fireParserUpdate();
                System.out.println("Parsing");
                lastAction = -1;
            }
        }
    }

    @Override
    public void documentInserted(JPopupMenu menu) {
        super.documentInserted(menu);
        JMenuItem item = new JMenuItem("Eigenschaften");
        item.setIcon(de.blitzcoder.collide.icons.Icon.load("file_text.png"));

        item.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                new CodeStatsWindow(BlitzMaxCodeDocument.this);
            }
        });

        menu.add(item);
    }
}
